#include "functions.hpp"
//returns true if the file exists
//false if it doesn't
//inputs:
//	string containting the path to the file
bool FileExists(string strFilename) {
    struct stat stFileInfo;
    bool blnReturn;
    int intStat;
    // Attempt to get the file attributes
    intStat = stat(strFilename.c_str(),&stFileInfo);
    if (intStat == 0) {
        // We were able to get the file attributes
        // so the file obviously exists.
        blnReturn = true;
    } else {
        // We were not able to get the file attributes.
        // This may mean that we don't have permission to
        // access the folder which contains this file. If you
        // need to do that level of checking, lookup the
        // return values of stat which will give you
        // more details on why stat failed.
        blnReturn = false;
    }
    return(blnReturn);
}
//converts the input to lowercase
string tolowercase(string str) {
    for (int i=0;i<(int)str.length();i++)
        if (str[i] >= 0x41 && str[i] <= 0x5A)
            str[i] = str[i] + 0x20;
    return str;
}
//writes file_content to the output file
//inputs:
//	vector<string> containing the file content that you want to write
//	const char* containing the path to the file
void write_file(vector<string> file_content,const char* path) {
    //open the file to write to
    outfile.open(path);
    //setup the iterator to step through the file with
    vector<string>::iterator it = file_content.begin();
    //write the first line
    outfile <<*it << nl;
    //loop through the rest and write the lines and increase the position
    while (++it!=file_content.end()) {
        outfile<<*it << nl;
    }
    //close the file now that it is finished
    outfile.close();
}
//will output the message and send it to the logfile if -l flag is set
void write(string content,string color, bool force) {
	if(verbose||force){
		if(allow_color)
			cout << "\033[" << color<< "m" << content << "\033[0m" << nl;
		else
			cout << content << nl;
	}
	if(log_file)
		logfile<<content<<nl;
}
//will output the message sent to it and close the logfile if open
void ewrite(string content,string color,bool force) {
	if(verbose||force){
		if(allow_color)
			cout << "\033[" << color<< "m" << content << "\033[0m" << nl;
		else
			cout << content << nl;
	}
	if(log_file){
		logfile<<content<<nl;
		logfile.close();
	}
}
void help(string title, string content){
	if(allow_color)
		cout << "            \033[34m" << title << "\033[0m		" << content << "\033[0m" << nl;
	else
		cout << "            " << title << "		" << content <<  nl;
}
//inserts a line in a vector<string>
void insert_vs(vector<string>& vstring,vector<string> vstring2,int& line_amount,int line) {
    //store the pointer to the first vector<string>'s first element in it
    vector<string>::iterator it = vstring.begin();
    //change the pointer of the first vector<string> to the correct line
    for (int i=0;i!=line+1;i++)
        ++it;
    //erase the line
    vstring.erase(it);
    //insert the second vector<string> into the first vector<string> at the correct line
    vstring.insert(it,vstring2.begin(),vstring2.end());
    //reset the pointer to the first vector<string>'s element
    it = vstring.begin();
    //set the line_amount to 0
    line_amount=0;
    //count up the total lines in the first vector<string>
    while (++it!=vstring.end())
        line_amount++;
}
//grabs a files contents and places them in a vector<string>
bool read_file(vector<string>& file, int& line_amount,const char* path) {
    //check if the file exists
    if (FileExists(path)) {
        ifstream readfile;
        //open the first file for reading
        readfile.open(path);
        //create a tmp string to store the content from the file
        string tmp;
        //increase file_line_amount by one
        //get the next line in the file and push it onto the array
        while ( getline( readfile, tmp ) ) {
            file.push_back(tmp);
        }
        //close the file because all the data we need is in file_content
        readfile.close();
        return(true);
    }
    else {
        cout << "\033[1;31mError! "<<path<<" does not exist!\033[0m"<<nl;
        return(false);
    }
}
/**
 * C++ version 0.4 std::string style "itoa":
 * Contributions from Stuart Lowe, Ray-Yuan Sheu,
 * Rodrigo de Salvo Braz, Luc Gallant, John Maloney
 * and Brian Hunt
 */
std::string itoa(int value, int base) {
	std::string buf;
	// check that the base if valid
	if (base < 2 || base > 16) return buf;
	enum { kMaxDigits = 35 };
	buf.reserve( kMaxDigits ); // Pre-allocate enough space.
	int quotient = value;
	// Translating number to string with base:
	do {
		buf += "0123456789ABCDEF"[ abs( quotient % base ) ];
		quotient /= base;
	} while ( quotient );
	// Append the negative sign
	if ( value < 0) buf += '-';
	reverse( buf.begin(), buf.end() );
	return buf;
}
//removes all trailing whitespaces including newlines of any sort and replaces with the standard \n
void fix_line_newline(string& s){
	string::size_type pos = s.length();
	while(pos!=0 && isspace(atoi(s.substr(pos,0).c_str())))
		pos--;
	if(pos!=0){
		s.erase(pos);
		s.append("\n");
	}
}
//returns true if val is in array
bool in_array(char val, char* array) {
	for (unsigned int i=0; i<=strlen(array); i++) {
		if (val == array[i]) {
			return true;
		}
	}
	return false;
}
//returns the index of the character if it is in array -1 otherwise
int in_array_int(char val, char* array) {
	for (unsigned int i=0; i<=strlen(array); i++) {
		if (val == array[i]) {
			return i;
		}
	}
	return -1;
}